package com.example.javaapitest.config;

import com.alibaba.fastjson.JSONPath;
import com.example.javaapitest.util.ReportUtil;
import com.example.javaapitest.util.StringReplaceUtil;
import com.example.javaapitest.util.functionUtil;
import org.junit.Assert;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class TestBase {
    /**
     * 公共参数数据池（全局可用）
     */
    private static Map<String, String> saveDatas = new HashMap<String, String>();

    /**
     * 替换符，如果数据中包含“${}”则会被替换成公共参数中存储的数据
     */
    protected Pattern replaceParamPattern = Pattern.compile("\\$\\{(.*?)\\}");

    /**
     * 获取公共数据池中的数据
     *
     * @param key
     *            公共数据的key
     * @return 对应的value
     */
    protected Pattern funPattern = Pattern
            .compile("__(\\w*?)\\((([\\w\\\\\\/:\\.\\$]*,?)*)\\)");

    protected String getSaveData(String key) {
        if ("".equals(key) || !saveDatas.containsKey(key)) {
            return null;
        } else {
            return saveDatas.get(key);
        }
    }
    protected void setSaveDatas(Map<String, String> map) {
        saveDatas.putAll(map);
    }

    /**
     * 取公共参数 并替换参数，处理${}
     * @param param
     * @return
     */
    protected String getCommonParam(String param) {
        if (StringReplaceUtil.isEmpty(param)) {     //stringUtil后续进行说明
            return "";
        }
        Matcher m = replaceParamPattern.matcher(param);// 取公共参数正则
        while (m.find()) {
            String replaceKey = m.group(1);
            // 如果公共参数池中未能找到对应的值，该用例失败。
            Assert.assertNotNull(replaceKey,
                    String.format("格式化参数失败，公共参数中找不到%s。", replaceKey));
            String value;
            // 从公共参数池中获取值
            value = getSaveData(replaceKey);
            //如果值不为空，则将参数替换为公共参数池里读取到的value的值。
            if(null != value) {
                param = param.replace(m.group(), value);
                //如果值为空，则将参数替换为字符串“null”
            }else {
                param = param.replace(m.group(), "null");
            }
        }
        return param;
    }

    /**
     * 提取json串中的值保存至公共池中
     *
     * @param json
     *            将被提取的json串。
     * @param allSave
     *            所有将被保存的数据：xx=$.jsonpath.xx;将$.jsonpath.
     *            xx提取出来的值存放至公共池的xx中
     */
    protected void saveResult(String json, String allSave) {
        if (null == json || "".equals(json) || null == allSave
                || "".equals(allSave)) {
            return;
        }
        allSave = getCommonParam(allSave);
        String[] saves = allSave.split(";");
        String key, value;
        for (String save : saves) {
            Pattern pattern = Pattern.compile("([^;=]*)=([^;]*)");
            Matcher m = pattern.matcher(save.trim());
            while (m.find()) {
                key = getBuildValue(json, m.group(1));  //getBuildValue的方法后续说明
                value = getBuildValue(json, m.group(2));
                ReportUtil.log(String.format("存储公共参数   %s值为：%s.", key, value));
                saveDatas.put(key, value);
            }
        }
    }

    /**
     * 获取格式化后的值
     *
     * @param sourchJson
     * @param key
     * @return
     */
    private String getBuildValue(String sourchJson, String key) {
        key = key.trim();
        Matcher funMatch = funPattern.matcher(key); //funPattern为函数匹配正则表达式，后续进行说明
        if (key.startsWith("$.")) {// 如果为JSONPath，获取该JSONPath对应的值（对象）
            Object x = JSONPath.read(sourchJson, key);
            //空值处理
            if(x == null) {
                key = (String)x;
            }else {
                key = x.toString();
            }
            //如果匹配到的是自定义函数，则先解析该自定义函数的参数，若该自定义函数的参数中有JSONPath，则对该JSONPath取值，并对应转成字符串对象。
        } else if (funMatch.find()) {
            String args = funMatch.group(2);
            String[] argArr = args.split(",");
            for (int index = 0; index < argArr.length; index++) {
                String arg = argArr[index];
                if (arg.startsWith("$.")) {
                    argArr[index] = JSONPath.read(sourchJson, arg).toString();
                }
            }
            String value = functionUtil.getValue(funMatch.group(1), argArr); // functionUtil为自定义函数工具类，后续说明
            key = StringReplaceUtil.replaceFirst(key, funMatch.group(), value);
        }
        return key;
    }
}
